#include <cassert>
#include "bouclejeu-SDL.h"



const int TAILLE_SPRITE=32;

SDL_Surface *SDL_load_image(const char* filename );
void SDL_apply_surface( SDL_Surface* source, SDL_Surface* destination, int x, int y );



sdlJeu* sdlJeuCreer(const int map[HAUTEUR][LARGEUR])
{
    sdlJeu* sj;
    sj=(sdlJeu*)malloc(sizeof(sdlJeu));
    sdlJeuInit(sj,map);
    return sj;
}

void sdlJeuInit(sdlJeu* sj,const int map[HAUTEUR][LARGEUR])
 {

    sj->jeu=creerJeu(map);
    SDL_Color couleurTexte = {250, 250, 250};

	assert(   SDL_Init( SDL_INIT_EVERYTHING )!= -1 );

	int dimx, dimy;
	dimx = getDimxTer( getTerrainJeu(sj->jeu) );
	dimy = getDimyTer( getTerrainJeu(sj->jeu) );
	dimx = dimx * TAILLE_SPRITE;
	dimy = dimy * TAILLE_SPRITE;
	sj->ecran = SDL_SetVideoMode(   dimx+200, dimy, 32, SDL_SWSURFACE );
	assert( sj->ecran );
	SDL_WM_SetCaption( "CasseBrique v0.1", NULL );

	sj->balle = SDL_load_image("data/balle.bmp");
	SDL_SetColorKey(sj->balle,SDL_SRCCOLORKEY,SDL_MapRGB(sj->ecran->format,255,255,0));
	if (!sj->balle) sj->balle = SDL_load_image("../data/balle.bmp");
	assert( sj->balle );

	sj->balle2 = SDL_load_image("data/balle2.bmp");
	SDL_SetColorKey(sj->balle2,SDL_SRCCOLORKEY,SDL_MapRGB(sj->ecran->format,255,255,0));
	if (!sj->balle2) sj->balle2 = SDL_load_image("../data/balle2.bmp");
	assert( sj->balle2 );

	sj->brique = SDL_load_image("data/brique.bmp");
    if (!sj->brique) sj->brique = SDL_load_image("../data/brique.bmp");
    assert( sj->brique);

	sj->barre = SDL_load_image("data/barre.bmp");
	if (!sj->barre) sj->barre = SDL_load_image("../data/barre.bmp");
	assert( sj->barre);

	sj->brique2 = SDL_load_image("data/brique2.bmp");
	if (!sj->brique2) sj->brique2 = SDL_load_image("../data/brique2.bmp");
	assert( sj->brique2);

	sj->fond = SDL_load_image("data/fond.bmp");
	if (!sj->fond) sj->fond = SDL_load_image("../data/fond.bmp");
	assert( sj->fond);

	sj->GameOver = SDL_load_image("data/gameover.bmp");
	if (!sj->GameOver) sj->GameOver = SDL_load_image("../data/gameover.bmp");
	assert( sj->GameOver);

	sj->vie = SDL_load_image("data/vie.bmp");
	SDL_SetColorKey(sj->vie,SDL_SRCCOLORKEY,SDL_MapRGB(sj->ecran->format,255,255,0));
	if (!sj->vie) sj->vie = SDL_load_image("../data/vie.bmp");
	assert( sj->vie);

	sj->mort = SDL_load_image("data/mort.bmp");
	SDL_SetColorKey(sj->mort,SDL_SRCCOLORKEY,SDL_MapRGB(sj->ecran->format,255,255,0));
	if (!sj->mort) sj->mort = SDL_load_image("../data/mort.bmp");
	assert( sj->mort);

	sj->acier = SDL_load_image("data/acier.bmp");
	SDL_SetColorKey(sj->acier,SDL_SRCCOLORKEY,SDL_MapRGB(sj->ecran->format,255,255,0));
	if (!sj->acier) sj->acier = SDL_load_image("../data/acier.bmp");
	assert( sj->acier);

	sj->police = TTF_OpenFont("data/police.ttf", 25);
	assert(sj->police);
	sj->texte = TTF_RenderText_Blended(sj->police, "Vie : ",  couleurTexte);
}



void sdljeuAff(sdlJeu* sj)
{
    int i;
    if(sj->jeu->vie<0)
    {
        SDL_apply_surface(  sj->GameOver, sj->ecran,  0 , 0);
    }
    else{
	//Remplir l'écran de blanc
    //TTF_Init();
    SDL_Color couleurTexte = {250, 250, 250};
    char afficheVie[200];
	SDL_FillRect( sj->ecran, &(sj->ecran->clip_rect), SDL_MapRGB( sj->ecran->format, 25, 25, 25));
	//SDL_Rect position;
   // TTF_Font *police = NULL;
    //SDL_Surface *texte = NULL;
    //SDL_Surface *ecran = NULL;
	int x,y;
	//SDL_Color couleurTexte = {250, 0, 250};
	const Terrain* ter = getTerrainJeu(sj->jeu);
	const Balle* bal = getBalleJeu(sj->jeu);
	const Barre* bar = getBarreJeu(sj->jeu);
    //assert(sj->police);
    //sj->texte = TTF_RenderText_Blended(sj->police, "Vie : ", couleurTexte);
    SDL_apply_surface(  sj->fond, sj->ecran,  0 , 0);
    for(i=0 ; i<(sj->jeu->t->opt->fin) ; i++)
    {
        if (sj->jeu->t->opt->tab[i]->numero == 1)
        {
            SDL_apply_surface(  sj->vie, sj->ecran, getPositionXOption(sj->jeu->t->opt->tab[i])*TAILLE_SPRITE, getPositionYOption(sj->jeu->t->opt->tab[i])*TAILLE_SPRITE);
        }
        if (sj->jeu->t->opt->tab[i]->numero == 2)
        {
            SDL_apply_surface(  sj->mort, sj->ecran, getPositionXOption(sj->jeu->t->opt->tab[i])*TAILLE_SPRITE, getPositionYOption(sj->jeu->t->opt->tab[i])*TAILLE_SPRITE);
        }
        if (sj->jeu->t->opt->tab[i]->numero == 3)
        {
            SDL_apply_surface(  sj->acier
							, sj->ecran, getPositionXOption(sj->jeu->t->opt->tab[i])*TAILLE_SPRITE, getPositionYOption(sj->jeu->t->opt->tab[i])*TAILLE_SPRITE);
        }

    }
	for(x=0;x<getDimxTer(ter);x++){
		for(y=0;y<getDimyTer(ter);y++){
			if (getResistanceBrique(getBriqueTer(ter,x,y))==1){
				SDL_apply_surface(  sj->brique, sj->ecran, x*TAILLE_SPRITE, (y)*TAILLE_SPRITE);
		}
            else if (getResistanceBrique(getBriqueTer(ter,x,y))==2)
            {
                SDL_apply_surface(  sj->brique2, sj->ecran, x*TAILLE_SPRITE, (y)*TAILLE_SPRITE);
            }}}
	// Copier le sprite de la balle sur sj.ecran
	if (getEtatBal(sj->jeu->bl) == 1)
	{
	  	SDL_apply_surface(  sj->balle, sj->ecran, getPositionXBal(bal)*TAILLE_SPRITE,  (getPositionYBal(bal))*TAILLE_SPRITE );
	}
	else
	{
        SDL_apply_surface(  sj->balle2, sj->ecran, getPositionXBal(bal)*TAILLE_SPRITE,  (getPositionYBal(bal))*TAILLE_SPRITE );
	}
	SDL_apply_surface(  sj->barre, sj->ecran,  getGaucheBar(bar)*TAILLE_SPRITE , getHauteurBar(bar)*TAILLE_SPRITE);
	SDL_apply_surface(  sj->texte, sj->ecran,  650 , 20);
	sprintf(afficheVie, "%d", sj->jeu->vie);
	sj->texte2 = TTF_RenderText_Blended(sj->police, afficheVie,  couleurTexte);
	SDL_apply_surface(  sj->texte2, sj->ecran,  720 , 20);
	//position.x = 0;
    //position.y = 0;
   // SDL_BlitSurface(fond, NULL, ecran, &position);
    //SDL_Flip(ecran);
    //TTF_CloseFont(police);
   // SDL_FreeSurface(texte);
}}



void sdljeuBoucle(sdlJeu* sj)
{
	SDL_Event event;
	bool quit = false;
	int xs,ys;

	sdljeuAff( sj );
	assert( SDL_Flip( sj->ecran )!=-1 );
	lacheBal(sj->jeu->bl, sj->jeu->t,0,1);

	// tant que ce n'est pas la fin ...
	while ( quit == false )
	{
		// tant qu'il y a des evenements à traiter : cette boucle n'est pas bloquante
		while ( SDL_PollEvent( &event ) )
		{
			// Si l'utilisateur a cliqué sur la croix de fermeture
			if ( event.type == SDL_QUIT ) quit = true;


            sdljeuAff( sj );
        //calculerPosition(jeu->bl);

        if(getPositionYBal(sj->jeu->bl)>getHauteurBar(sj->jeu->br))
        {
            setVieJeu(sj->jeu);
            libereTouteOptionTableau(sj->jeu->t->opt);
            initialiseTableau(sj->jeu->t->opt);
            initBal(sj->jeu->bl, sj->jeu->br);
            lacheBal(sj->jeu->bl,sj->jeu->t,0,1);
        }

        if(estVideTer(sj->jeu->t)==1)
        {
            quit = true;
            break;
        }



			// Si une touche est enfoncée
			if ( event.type == SDL_KEYDOWN )
			{
				switch ( event.key.keysym.sym )
				{
				case SDLK_LEFT:
					actionClavierJeu( sj->jeu, 'g');
					break;
				case SDLK_RIGHT:
					actionClavierJeu( sj->jeu, 'd');
					break;
				default: break;
				}
			}
			if(event.type == SDL_MOUSEMOTION)
			{
			    SDL_GetMouseState(&xs,&ys);
			    //sj->jeu->br->positionX = xs;
                actionSourisJeu(sj->jeu,(xs/32));
			    //actionClavierJeu( sj->jeu, 'd');
			}

		}
        SDL_Delay(200);
        calculerNouvelleDirectionJeu(sj->jeu);
		setPositionBal(sj->jeu->bl);
		rattrapeOptionJeu(sj->jeu);
		touteOptionTombeTer(sj->jeu->t);


		// on affiche le jeu sur le buffer caché
		sdljeuAff( sj );

		// on permute les deux buffers (cette fonction ne doit se faire qu'une seule fois dans a boucle)
		SDL_Flip( sj->ecran );
	}
}


void sdljeuDetruit( sdlJeu* sj)
{
	SDL_FreeSurface( sj->balle );
	SDL_FreeSurface( sj->brique );
	SDL_FreeSurface( sj->barre );
	SDL_Quit();
}



SDL_Surface *SDL_load_image(const char* filename )
{
	//Temporary storage for the image that's loaded
	SDL_Surface* loadedImage = NULL;

	//The optimized image that will be used
	SDL_Surface* optimizedImage = NULL;

	//Load the image
	loadedImage = SDL_LoadBMP( filename );

	//If nothing went wrong in loading the image
	if ( loadedImage != NULL )
	{
		//Create an optimized image
		optimizedImage = SDL_DisplayFormat( loadedImage );

		//Free the old image
		SDL_FreeSurface( loadedImage );
	}

	//Return the optimized image
	return optimizedImage;
}


void SDL_apply_surface( SDL_Surface* source, SDL_Surface* destination, int x, int y )
{
	//Make a temporary rectangle to hold the offsets
	SDL_Rect offset;

	//Give the offsets to the rectangle
	offset.x = x;
	offset.y = y;

	//Blit the surface
	SDL_BlitSurface( source, NULL, destination, &offset );
}

